<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/72X72.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/48X48.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/32X32.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"issacyoung.cn","root":"/","scheme":"Pisces","version":"7.7.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="SpringBoot 为神马读源码？知其然知其所以然，触类旁通，究其原理，自我折磨的过程中，反复咀嚼、思考。SpringBoot 原旨是为了快速开发网站，其一网站，访问指定服务器的资源，现如今资源大多是数据库，从web诞生之始，一如既是；其二开发，不是运维、不是设计，在于提供给开发人员；其三，快速是相对而言，原有的 ssm过于繁琐，在于模块的整合、配置。">
<meta property="og:type" content="article">
<meta property="og:title" content="一步步读SpringBoot源码">
<meta property="og:url" content="http://issacyoung.cn/2020/02/28/%E4%B8%80%E6%AD%A5%E6%AD%A5%E8%AF%BBSpringBoot%E6%BA%90%E7%A0%81/index.html">
<meta property="og:site_name" content="Young‘s River">
<meta property="og:description" content="SpringBoot 为神马读源码？知其然知其所以然，触类旁通，究其原理，自我折磨的过程中，反复咀嚼、思考。SpringBoot 原旨是为了快速开发网站，其一网站，访问指定服务器的资源，现如今资源大多是数据库，从web诞生之始，一如既是；其二开发，不是运维、不是设计，在于提供给开发人员；其三，快速是相对而言，原有的 ssm过于繁琐，在于模块的整合、配置。">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-02-28T00:49:18.000Z">
<meta property="article:modified_time" content="2022-03-19T06:34:30.606Z">
<meta property="article:author" content="Issac Young">
<meta property="article:tag" content="java">
<meta property="article:tag" content="SpringBoot">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://issacyoung.cn/2020/02/28/%E4%B8%80%E6%AD%A5%E6%AD%A5%E8%AF%BBSpringBoot%E6%BA%90%E7%A0%81/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: false,
    isPost: true
  };
</script>

  <title>一步步读SpringBoot源码 | Young‘s River</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

<link rel="alternate" href="/atom.xml" title="Young‘s River" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <div>
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Young‘s River</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">一个正能量的程序员，喜欢码字，热爱运动，向往自由</p>
  </div>

  <div class="site-nav-right"></div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

  <a href="https://github.com/IssacYoung2013" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block " lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://issacyoung.cn/2020/02/28/%E4%B8%80%E6%AD%A5%E6%AD%A5%E8%AF%BBSpringBoot%E6%BA%90%E7%A0%81/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/author.jpg">
      <meta itemprop="name" content="Issac Young">
      <meta itemprop="description" content="现代生活工作节奏越来越快，需要有时间和空间沉淀积累，将知识点规划成树，记录自己的感悟心得。">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Young‘s River">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          一步步读SpringBoot源码
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-02-28 08:49:18" itemprop="dateCreated datePublished" datetime="2020-02-28T08:49:18+08:00">2020-02-28</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2022-03-19 14:34:30" itemprop="dateModified" datetime="2022-03-19T14:34:30+08:00">2022-03-19</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/java/" itemprop="url" rel="index">
                    <span itemprop="name">java</span>
                  </a>
                </span>
            </span>

          
            <span class="post-meta-item" title="阅读次数" id="busuanzi_container_page_pv" style="display: none;">
              <span class="post-meta-item-icon">
                <i class="fa fa-eye"></i>
              </span>
              <span class="post-meta-item-text">阅读次数：</span>
              <span id="busuanzi_value_page_pv"></span>
            </span><br>
            <span class="post-meta-item" title="本文字数">
              <span class="post-meta-item-icon">
                <i class="fa fa-file-word-o"></i>
              </span>
                <span class="post-meta-item-text">本文字数：</span>
              <span>9.8k</span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="SpringBoot"><a href="#SpringBoot" class="headerlink" title="SpringBoot"></a>SpringBoot</h1><blockquote>
<p>为神马读源码？知其然知其所以然，触类旁通，究其原理，自我折磨的过程中，反复咀嚼、思考。SpringBoot 原旨是为了快速开发网站，其一网站，访问指定服务器的资源，现如今资源大多是数据库，从web诞生之始，一如既是；其二开发，不是运维、不是设计，在于提供给开发人员；其三，快速是相对而言，原有的 ssm过于繁琐，在于模块的整合、配置。</p>
</blockquote>
<a id="more"></a>

<p>查看官网的声明，SpringBoot的宗旨如下：</p>
<ul>
<li>创建单体的Spring应用</li>
<li>内置 Tomcat、Jetty、Undertow，无需部署war包</li>
<li>各种 starter 插件，简化配置</li>
<li>支持Spring和第三方jar自动装配</li>
<li>提供 metrics、health checks 额外的配置</li>
<li>无需xml</li>
</ul>
<h2 id="搭建源码环境"><a href="#搭建源码环境" class="headerlink" title="搭建源码环境"></a>搭建源码环境</h2><ul>
<li><p>下载github源码</p>
</li>
<li><p>修改成调试版本，构建上传本地maven仓库</p>
<p><code>mvn install -U -DskipTests</code></p>
<p>注释添加中文会有报错，需要执行下面命令</p>
<p><code>mvn spring-javaformat:apply</code></p>
</li>
</ul>
<h2 id="如何使用"><a href="#如何使用" class="headerlink" title="如何使用"></a>如何使用</h2><blockquote>
<p>具体一步步使用无需赘述，具体看看如何创建单体Spring应用。</p>
</blockquote>
<ol>
<li><p>创建 pom 文件，引入依赖，这里以 maven 构建工程为例</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">"http://maven.apache.org/POM/4.0.0"</span> <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xsi:schemaLocation</span>=<span class="string">"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.example<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>myproject<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="comment">&lt;!-- Inherit defaults from Spring Boot 指定默认版本--&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.5.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="comment">&lt;!-- Add typical dependencies for a web application web依赖集合--&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>编写代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.boot.*;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.autoconfigure.*;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.*;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@EnableAutoConfiguration</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Example</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@RequestMapping</span>(<span class="string">"/"</span>)</span><br><span class="line">	<span class="function">String <span class="title">home</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="string">"Hello World!"</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SpringApplication.run(Example<span class="class">.<span class="keyword">class</span>, <span class="title">args</span>)</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>如上的代码，启动main函数，web应用就起来了。看起来寥寥数语，究竟内藏什么玄呢？<code>@RestController</code> 给阅读代码的人提示被标注的类扮演处理 web 请求的角色， <code>@RequestMapping</code> 注解则扮演引路的角色，将访问路径映射到具体的方法上，同时 <code>@RestController</code>告诉 Spring 渲染的结果直接返回给调用者。</p>
<p><code>@EnableAutoConfiguration</code>注解则告诉 Spring Boot 是基于添加的依赖进行 Spring 配置，这里添加的是<code>spring-boot-starter-web</code>内置Tomcat、SpringMVC，表明即将启动的是个 web 工程。</p>
<p>至于 main 方法的逻辑，SpringApplication 调用 run 方法启动应用，装配 Spring，开启 Tomcat Web 工程，Example 作为主容器。</p>
</li>
<li><p>启动</p>
</li>
<li><p>构建可执行 jar</p>
<p>java 未提供装载嵌套的 jar包的标准方式，Spring Boot 提供了将程序依赖打包成一个压缩包的插件，<code>spring-boot-maven-plugin</code>，构建生成 xxx.jar 即是依赖的压缩包，可以直接运行。</p>
</li>
</ol>
<h3 id="依赖管理"><a href="#依赖管理" class="headerlink" title="依赖管理"></a>依赖管理</h3><p>构建依赖体系，每一个版本的 springboot 集成特定版本的依赖包括第三方依赖。</p>
<p>继承父工程的依赖 <code>spring-boot-starter-parent</code>，提供了如下特征：</p>
<ul>
<li>java1.8编译</li>
<li>UTF-8编码</li>
<li>版本管理…</li>
</ul>
<ol>
<li><p>继承父starter</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- Inherit defaults from Spring Boot --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.5.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>添加其他依赖无需指定版本号，如果需要覆盖父工程的集合</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">spring-data-releasetrain.version</span>&gt;</span>Fowler-SR2<span class="tag">&lt;/<span class="name">spring-data-releasetrain.version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>使用<code>&lt;dependencyManagement&gt;</code> 、<code>&lt;scope&gt;import&lt;/scope&gt;</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="comment">&lt;!-- Import dependency management from Spring Boot --&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-dependencies<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.5.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">type</span>&gt;</span>pom<span class="tag">&lt;/<span class="name">type</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">scope</span>&gt;</span>import<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencyManagement</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>对于有父依赖工程的项目，使用<code>dependecyManagement</code>，同时可以指定版本覆盖集合依赖</p>
</li>
</ol>
<h3 id="代码框架"><a href="#代码框架" class="headerlink" title="代码框架"></a>代码框架</h3><p>springboot 对代码框架没有严格要求，默认从 main 程序入口扫描实体类。<code>@SpringBootApplication</code> 相当于 <code>@EnableAutoConfiguration</code> 和 <code>@ComponentScan</code>。</p>
<h3 id="配置类"><a href="#配置类" class="headerlink" title="配置类"></a>配置类</h3><p><code>@Configuration</code>修饰单个类相当于原来的 Spring xml ，同时 <code>@Import</code> 可以引入附加的配置类，<code>@ComponentScan</code>可以扫描 spring 组件，包括 <code>@Configuration</code>，当然 xml 文件也可以通过 <code>@ImportResource</code>引入。 </p>
<h3 id="自动装配"><a href="#自动装配" class="headerlink" title="自动装配"></a>自动装配</h3><p>springboot 根据添加的依赖自动装配类到程序中，通过 <code>@EnableAutoConfiguration</code>或者 <code>@SpringBootApplication</code>修饰 <code>@Configuration</code>类。</p>
<p>exclude 可以指定排除某个类的自动装配。</p>
<h3 id="实体类和依赖注入"><a href="#实体类和依赖注入" class="headerlink" title="实体类和依赖注入"></a>实体类和依赖注入</h3><p>通过 <code>@Autowired</code> 可以修饰构造器注入，如果只有一个构造器，可以忽略。</p>
<h3 id="SpringBootApplication"><a href="#SpringBootApplication" class="headerlink" title="@SpringBootApplication"></a>@SpringBootApplication</h3><p>相当于 <code>@EnableAutoConfiguration</code>、<code>@ComponentScan</code>、<code>@Configuration</code>三者集合。</p>
<h3 id="Developer-Tools"><a href="#Developer-Tools" class="headerlink" title="Developer Tools"></a>Developer Tools</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-devtools<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>springboot 利用缓存机制提高性能，比如：静态资源，开发环境可以利用 developer tools 关闭缓存。在类文件发生修改时自动重启服务，可以指定排除的文件目录，也可以指定额外的监控目录。</p>
<h2 id="系统初始化器"><a href="#系统初始化器" class="headerlink" title="系统初始化器"></a>系统初始化器</h2><p>ApplicationContextInitalizer ，spring容器刷新之前回调函数。</p>
<p>SpringFactoriesLoader </p>
<p>从类路径jar包读取特定文件实现拓展类的载入。</p>
<p>上下文刷新refresh方法前调用</p>
<p>一般设置 web 环境变量</p>
<h2 id="监听器"><a href="#监听器" class="headerlink" title="监听器"></a>监听器</h2><p>监听器模式。</p>
<h2 id="Bean-解析"><a href="#Bean-解析" class="headerlink" title="Bean 解析"></a>Bean 解析</h2><p>xml注册bean</p>
<p>注解方式</p>
<ul>
<li>@Component</li>
<li>FactoryBean，@Configuration</li>
<li>实现 BeanDefinitionRegistryPostProcessor</li>
<li>实现 ImportBeanDefinitionRegistrar</li>
</ul>
<p>refresh方法</p>
<ul>
<li><p>prefresh</p>
<ul>
<li>容器状态设置</li>
<li>初始化属性设置</li>
<li>必备属性校验</li>
</ul>
</li>
<li><p>obtainFreshBeanFactory</p>
<ul>
<li>设置beanFactory序列化id</li>
<li>获取beanFactory</li>
</ul>
</li>
<li><p>prepareBeanFactory</p>
<ul>
<li>设置beanFacotru属性</li>
<li>设置后置处理器</li>
</ul>
</li>
<li><p>postProccessBeanFactory</p>
<ul>
<li>子类重写以在beanFacotry创建后处理</li>
</ul>
</li>
<li><p>invokeBeanFactoryPostProcessors</p>
<ul>
<li>调用 BeanDefinitionRegistryPostProcessor 实现向容器内添加bean的定义</li>
<li>调用 BeanFactory</li>
</ul>
</li>
<li><p>registerBeanPostProcessors</p>
<ul>
<li>找到 BeanPostProcessor 实现</li>
<li>注册到容器</li>
</ul>
</li>
<li><p>initApplicationEventMulticaster</p>
<ul>
<li>初始化事件广播器</li>
</ul>
</li>
<li><p>registerListeners</p>
<ul>
<li>添加事件到广播器</li>
<li>执行早起事件</li>
</ul>
</li>
<li><p>finishBeanFactoryInitialization</p>
</li>
</ul>
<h3 id="Bean-实例化解析"><a href="#Bean-实例化解析" class="headerlink" title="Bean 实例化解析"></a>Bean 实例化解析</h3><p>围绕 BeanDefinition，最常见的 RootBeanDefinition</p>
<p>refresh方法流程</p>
<h2 id="Banner解析"><a href="#Banner解析" class="headerlink" title="Banner解析"></a>Banner解析</h2><h2 id="属性配置解析"><a href="#属性配置解析" class="headerlink" title="属性配置解析"></a>属性配置解析</h2><ul>
<li>Spring Aware介绍</li>
</ul>
<h3 id="属性配置"><a href="#属性配置" class="headerlink" title="属性配置"></a>属性配置</h3><ol>
<li>DevTools</li>
<li>测试环境 @TestPropertySource</li>
<li>测试环境 properties 属性</li>
<li>命令行参数</li>
<li>SPRING_APPLICATION_JOSN 属性</li>
<li>ServletConfig初始化参数</li>
<li>ServletContext</li>
<li>JDNI</li>
<li>Java系统属性</li>
<li>操作系统环境变量</li>
<li>RadomValuePropertySource</li>
<li>jar包外的 application-{profile}.properties</li>
<li>jar包内的 application-{profile}.properties</li>
<li>jar包外的 application.properties</li>
<li>jar包内的 application.properties</li>
<li>@PropertySource</li>
<li>默认属性</li>
</ol>
<h3 id="Aware"><a href="#Aware" class="headerlink" title="Aware"></a>Aware</h3><p>Bean 感知不到容器的存在，需要使用Spring容器的功能资源。使用 Aware，Bean 和容器强耦合。</p>
<p>常用的 Aware ： EnvironmentAware、ApplicationContextAware、BeanFactoryAware。</p>
<p>调用原理：</p>
<ul>
<li>doCreateBean</li>
<li>initalizeBean</li>
<li>invokeAwareMethods</li>
<li>applyBeanPostProcessorBeforeInitialization</li>
<li>ApplicationContextAwareProssor</li>
</ul>
<h3 id="Environment-解析"><a href="#Environment-解析" class="headerlink" title="Environment 解析"></a>Environment 解析</h3><h2 id="Spring-Boot-特征"><a href="#Spring-Boot-特征" class="headerlink" title="Spring Boot 特征"></a>Spring Boot 特征</h2><p><code>SpringApplication.run</code> 静态方法启动。</p>
<h3 id="启动失败"><a href="#启动失败" class="headerlink" title="启动失败"></a>启动失败</h3><p><code>$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug</code> 可以查询启动日志</p>
<h3 id="个性化-banner"><a href="#个性化-banner" class="headerlink" title="个性化 banner"></a>个性化 banner</h3><p>在类路径下添加 <code>banner.txt</code>，或者指定<code>spring.banner.location</code> 指定文件，同时可以指定banner字符集<code>spring.banner.charset</code>。除了文本，也支持 <code>banner.gif</code>、<code>banner.jpg</code> 类路径下的图片，或者指定 banner图片<code>spring.banner.image.localtion</code></p>
<h3 id="事件和监听器"><a href="#事件和监听器" class="headerlink" title="事件和监听器"></a>事件和监听器</h3><p>Spring 框架中，<code>ContextRefreshedEvent</code>在上下文创建后创建，对于上下文创建之前的事件不能通过 <code>@Bean</code> 注册，可以通过 <code>SpringApplication.addListeners(...)</code>。</p>
<ol>
<li><code>ApplicationStartingEvent</code>，在注册监听器和初始化器操作外所有启动进程之前</li>
<li><code>ApplicationEnvironmentPreparedEvent</code>，<code>Environment</code> 使用时，但上下文创建之前</li>
<li><code>ApplicatioPreparedEvent</code> ，bean definitions 装载之后，refresh启动之前</li>
<li><code>ApplicationStartedEvent</code>，上下文刷新之后，application 和 command-line runner 调用之前</li>
<li><code>ApplicationReadyEvent</code>，application 和 command-line runner 调用之后，提示服务准备处理请求</li>
<li><code>ApplicationFailedEvent</code>，启动过程有异常</li>
</ol>
<h3 id="Web-Environment"><a href="#Web-Environment" class="headerlink" title="Web Environment"></a>Web Environment</h3><ul>
<li><code>AnnotationConfigServletWebServerApplicationContext</code> 使用了这个上下文类表示 Spring MVC</li>
<li><code>AnnotationConfigReactiveWebServerApplicationContext</code>，这个表示 Spring WebFlux</li>
<li>否则，使用<code>AnnotationConfigApplicationContext</code></li>
</ul>
<h3 id="ApplicationRunner-or-CommandLineRunner"><a href="#ApplicationRunner-or-CommandLineRunner" class="headerlink" title="ApplicationRunner or CommandLineRunner"></a>ApplicationRunner or CommandLineRunner</h3><p>在程序启动完成之前执行，两个接口都需要实现 run 方法。</p>
<h3 id="Application-Exit"><a href="#Application-Exit" class="headerlink" title="Application Exit"></a>Application Exit</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ExitCodeApplication</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> ExitCodeGenerator <span class="title">exitCodeGenerator</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 重写退出错误码</span></span><br><span class="line">        <span class="keyword">return</span> ()-&gt;<span class="number">42</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        System.exit(SpringApplication.exit(SpringApplication.run(ExitCodeApplication<span class="class">.<span class="keyword">class</span>,<span class="title">args</span>)))</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Externalized-Configuration"><a href="#Externalized-Configuration" class="headerlink" title="Externalized Configuration"></a>Externalized Configuration</h3><p>外部化的配置，支持 properties、YAML、环境变量、命令行参数个性化配置。</p>
<h4 id="配置随机值"><a href="#配置随机值" class="headerlink" title="配置随机值"></a>配置随机值</h4><p><code>RandomValuePropertySource</code>注入随机值，适用于测试、密钥。</p>
<h4 id="Application-Property-Files"><a href="#Application-Property-Files" class="headerlink" title="Application Property Files"></a>Application Property Files</h4><p><code>java -jar xxx.jar --spring.config.name=myproject</code>，指定配置文件</p>
<p><code>java -jar xxx.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties</code> </p>
<h4 id="Profile-specific-Properties"><a href="#Profile-specific-Properties" class="headerlink" title="Profile-specific Properties"></a>Profile-specific Properties</h4><p>指定环境变量，<code>application-{profile}.properties</code>，通过指定 spring.profiles.active 设置取的环境配置文件。</p>
<h4 id="Placeholders-in-Properties"><a href="#Placeholders-in-Properties" class="headerlink" title="Placeholders in Properties"></a>Placeholders in Properties</h4><p><code>application.properties</code> 可以填充环境变量或者之前定义的变量。</p>
<h4 id="Using-YAML-Instead-of-Properties"><a href="#Using-YAML-Instead-of-Properties" class="headerlink" title="Using YAML Instead of Properties"></a>Using YAML Instead of Properties</h4><p>更方便，广义的 JSON。</p>
<p>对于属性较多的节点，或者定义列表属性，书写更简洁。</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">my:</span></span><br><span class="line">  <span class="attr">servers:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">dev.exapmle.com</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">another.example.com</span></span><br></pre></td></tr></table></figure>

<p>支持多环境指定。</p>
<p>缺点在于，不能被 <code>@PropertySource</code>加载，会跟环境变量冲突。</p>
<h4 id="Type-safe-Configuration-Properties"><a href="#Type-safe-Configuration-Properties" class="headerlink" title="Type-safe Configuration Properties"></a>Type-safe Configuration Properties</h4><p>类型安全配置，使用 <code>@Value(&quot;${property}&quot;)</code>比较笨重，特别是同多层级里多属性。springboot 提供了强类型bean映射配置类，支持非严格的绑定，<code>@Value</code>支持 SPEL 表达式。</p>
<p><code>@ConfigurationProperties</code> 处理环境配置，不建议注入其他bean。<code>@ConfigurationProperties</code> 可以通过 <code>@EnableConfigurationProperties</code> 注入，也可以通过 <code>@Component</code>。</p>
<h5 id="Third-Party-Configuration"><a href="#Third-Party-Configuration" class="headerlink" title="Third-Party Configuration"></a>Third-Party Configuration</h5><p>例如，redis的配置注入。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ConfigurationProperties</span>(prefix = <span class="string">"another"</span>)</span><br><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> AnotherComponent <span class="title">anotherComponent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> anotherComponent();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="Relaxed-Binding"><a href="#Relaxed-Binding" class="headerlink" title="Relaxed Binding"></a>Relaxed Binding</h5><p>属性绑定并不严格，支持中间杠的 Kabab 风格（官方建议）、标准的驼峰、下划线风格。</p>
<h5 id="Merging-Complex-Types"><a href="#Merging-Complex-Types" class="headerlink" title="Merging Complex Types"></a>Merging Complex Types</h5><p>list属性是完全覆盖，map则是按key覆盖。</p>
<h5 id="Properties-Conersion"><a href="#Properties-Conersion" class="headerlink" title="Properties Conersion"></a>Properties Conersion</h5><p>属性转换，时间单位、数据大小。</p>
<h5 id="ConfigurationProperties-Validation"><a href="#ConfigurationProperties-Validation" class="headerlink" title="@ConfigurationProperties Validation"></a>@ConfigurationProperties Validation</h5><p><code>@Validated 和@NotNull</code>，配合修饰，校验。</p>
<h3 id="Profiles"><a href="#Profiles" class="headerlink" title="Profiles"></a>Profiles</h3><p><code>@Configuration</code> 可以被 <code>@Profile</code>修饰，指定环境。可以<code>spring.profiles.include:</code>添加环境变量，多值。</p>
<h3 id="Logging"><a href="#Logging" class="headerlink" title="Logging"></a>Logging</h3><p>springboot 使用通用的日志接口，实现开放，支持 <code>Java.Util.Logging</code>、<code>Log4J2</code>、<code>Logback</code>，也可以通过日志文件配置输出。</p>
<h4 id="Log-Format"><a href="#Log-Format" class="headerlink" title="Log Format"></a>Log Format</h4><ul>
<li>Date and Time</li>
<li>Log Level: ERROR、WARN、INFO、DEBUG、TRACE</li>
<li>Process ID</li>
<li><code>-</code>-<code>-</code> 用来区分实际的日志信息</li>
<li>Thread Name</li>
<li>Logger name：通常是源类文件</li>
<li>Log message</li>
</ul>
<h4 id="Console-Output"><a href="#Console-Output" class="headerlink" title="Console Output"></a>Console Output</h4><p>debug=true</p>
<h4 id="File-Output"><a href="#File-Output" class="headerlink" title="File Output"></a>File Output</h4><p>logging.file 或者 logging.path 设置文件输出文件或者目录</p>
<h4 id="Log-Levels"><a href="#Log-Levels" class="headerlink" title="Log Levels"></a>Log Levels</h4><p><code>logging.level.&lt;logger-name&gt;=&lt;level&gt;</code></p>
<h4 id="Custom-log-Configuration"><a href="#Custom-log-Configuration" class="headerlink" title="Custom log Configuration"></a>Custom log Configuration</h4><ul>
<li>Logback，<code>logback-spring.xml</code>、<code>logback-spring.groovy</code>、<code>logback.xml</code>、<code>logback.groovy</code></li>
<li>Log4j2，<code>log4j2-spring.xml</code>、<code>log4j2.xml</code></li>
<li>JDK，<code>logging.properties</code></li>
</ul>
<h4 id="Logback-Extensions"><a href="#Logback-Extensions" class="headerlink" title="Logback Extensions"></a>Logback Extensions</h4><p>logback.xml 已经预先加载，需要使用 <code>logback-spring.xml</code>或者定义<code>logging.config</code>。</p>
<h3 id="JSON"><a href="#JSON" class="headerlink" title="JSON"></a>JSON</h3><p>springboot 集成了Gson、Jackson、JSON-B，默认 jackson。</p>
<h3 id="Developing-Web-Applications"><a href="#Developing-Web-Applications" class="headerlink" title="Developing Web Applications"></a>Developing Web Applications</h3><p>使用内置 tomcat、jetty、undertow 创建 HTTP server。</p>
<h4 id="Spring-Web-MVC-Framework"><a href="#Spring-Web-MVC-Framework" class="headerlink" title="Spring Web MVC Framework"></a>Spring Web MVC Framework</h4><ul>
<li><p>Spring MVC Auto-configuration</p>
<ul>
<li><code>ContentNegotiatingViewResoler</code>和 <code>BeanNameViewResolver</code></li>
<li>自动注册，<code>Converter</code>、<code>GenericConverter</code>和<code>Formatter</code>。</li>
<li>支持 <code>HttpMessageConverters</code></li>
<li>自动注册 <code>MessageCodesResolver</code></li>
</ul>
</li>
<li><p>HttpMessageConverters</p>
</li>
<li><p>Custom JSON Serializers and Deserializers</p>
</li>
<li><p>MessageCodesResolver</p>
</li>
<li><p>Static Content</p>
</li>
<li><p>Welcome Page</p>
</li>
<li><p>Custom Favicon</p>
</li>
<li><p>Path Matching and Content Negotiation</p>
</li>
<li><p>ConfigurableWebBinddingInitalizer</p>
</li>
<li><p>Error Handling</p>
</li>
<li><p>CORS Support</p>
</li>
</ul>
<h4 id="Spring-WebFlux-Framework"><a href="#Spring-WebFlux-Framework" class="headerlink" title="Spring WebFlux Framework"></a>Spring WebFlux Framework</h4><p>异步非阻塞框架，响应式框架。</p>
<h4 id="Embedded-Servlet-Container-Support"><a href="#Embedded-Servlet-Container-Support" class="headerlink" title="Embedded Servlet Container Support"></a>Embedded Servlet Container Support</h4><p>支持 Tomcat、Jetty、Undertow</p>
<h3 id="Working-with-NoSQL-Technologies"><a href="#Working-with-NoSQL-Technologies" class="headerlink" title="Working with NoSQL Technologies"></a>Working with NoSQL Technologies</h3><h4 id="Redis"><a href="#Redis" class="headerlink" title="Redis"></a>Redis</h4><p>支持 Lettuce 和 Jedis 的客户端，默认是 Lettuce，也支持异步。</p>
<h4 id="MongoDB"><a href="#MongoDB" class="headerlink" title="MongoDB"></a>MongoDB</h4><h4 id="Neo4j"><a href="#Neo4j" class="headerlink" title="Neo4j"></a>Neo4j</h4><h4 id="Solr"><a href="#Solr" class="headerlink" title="Solr"></a>Solr</h4><h3 id="Caching"><a href="#Caching" class="headerlink" title="Caching"></a>Caching</h3><h4 id="Generic"><a href="#Generic" class="headerlink" title="Generic"></a>Generic</h4><h4 id="JCache"><a href="#JCache" class="headerlink" title="JCache"></a>JCache</h4><h4 id="EhCache"><a href="#EhCache" class="headerlink" title="EhCache"></a>EhCache</h4><h4 id="Redis-1"><a href="#Redis-1" class="headerlink" title="Redis"></a>Redis</h4><h4 id="Caffeine"><a href="#Caffeine" class="headerlink" title="Caffeine"></a>Caffeine</h4><p>java8重写 guava cache。</p>
<h3 id="Messages"><a href="#Messages" class="headerlink" title="Messages"></a>Messages</h3><p>消息系统，支持 JMS、ActiveMQ、RabbitMQ、Kafka</p>
<h3 id="Calling-REST-Services-with-RestTemplate"><a href="#Calling-REST-Services-with-RestTemplate" class="headerlink" title="Calling REST Services with RestTemplate"></a>Calling REST Services with <code>RestTemplate</code></h3><h3 id="Calling-REST-Services-with-WebClient"><a href="#Calling-REST-Services-with-WebClient" class="headerlink" title="Calling REST Services with WebClient"></a>Calling REST Services with <code>WebClient</code></h3><h3 id="Creating-Your-Own-Auto-Configuration"><a href="#Creating-Your-Own-Auto-Configuration" class="headerlink" title="Creating Your Own Auto-Configuration"></a>Creating Your Own Auto-Configuration</h3>
    </div>

    
    
    
<div>
  
    <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;">-------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------</div>
    
</div>

  
</div>
        <div class="reward-container">
  <div>辛苦码字分享，您的支持将鼓励我继续创作！</div>
  <button onclick="var qr = document.getElementById('qr'); qr.style.display = (qr.style.display === 'none') ? 'block' : 'none';">
    打赏
  </button>
  <div id="qr" style="display: none;">
      
      <div style="display: inline-block;">
        <img src="/images/wechatpay.jpg" alt="Issac Young 微信支付">
        <p>微信支付</p>
      </div>
      
      <div style="display: inline-block;">
        <img src="/images/alipay.jpg" alt="Issac Young 支付宝">
        <p>支付宝</p>
      </div>

  </div>
</div>

        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>Issac Young
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="http://issacyoung.cn/2020/02/28/%E4%B8%80%E6%AD%A5%E6%AD%A5%E8%AF%BBSpringBoot%E6%BA%90%E7%A0%81/" title="一步步读SpringBoot源码">http://issacyoung.cn/2020/02/28/一步步读SpringBoot源码/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fa fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

        

  <div class="followme">
    <p>欢迎关注我的其它发布渠道</p>

    <div class="social-list">

            <div class="social-item">
              <a target="_blank" class="social-link" href="/atom.xml">
                <span class="icon">
                  <i class="fa fa-rss"></i>
                </span>

                <span class="label">RSS</span>
              </a>
            </div>
    </div>
  </div>


      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/java/" rel="tag"><i class="fa fa-tag"></i># java</a>
              <a href="/tags/SpringBoot/" rel="tag"><i class="fa fa-tag"></i># SpringBoot</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/02/24/%E4%B8%80%E6%AD%A5%E6%AD%A5%E4%B9%8BDiscruotor-I/" rel="prev" title="一步步之Discruotor I">
      <i class="fa fa-chevron-left"></i> 一步步之Discruotor I
    </a></div>
      <div class="post-nav-item">
    <a href="/2021/03/04/%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92/" rel="next" title="学习计划">
      学习计划 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  

  </div>


          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let activeClass = CONFIG.comments.activeClass;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#SpringBoot"><span class="nav-number">1.</span> <span class="nav-text">SpringBoot</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#搭建源码环境"><span class="nav-number">1.1.</span> <span class="nav-text">搭建源码环境</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#如何使用"><span class="nav-number">1.2.</span> <span class="nav-text">如何使用</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#依赖管理"><span class="nav-number">1.2.1.</span> <span class="nav-text">依赖管理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#代码框架"><span class="nav-number">1.2.2.</span> <span class="nav-text">代码框架</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#配置类"><span class="nav-number">1.2.3.</span> <span class="nav-text">配置类</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#自动装配"><span class="nav-number">1.2.4.</span> <span class="nav-text">自动装配</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#实体类和依赖注入"><span class="nav-number">1.2.5.</span> <span class="nav-text">实体类和依赖注入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#SpringBootApplication"><span class="nav-number">1.2.6.</span> <span class="nav-text">@SpringBootApplication</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Developer-Tools"><span class="nav-number">1.2.7.</span> <span class="nav-text">Developer Tools</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#系统初始化器"><span class="nav-number">1.3.</span> <span class="nav-text">系统初始化器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#监听器"><span class="nav-number">1.4.</span> <span class="nav-text">监听器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Bean-解析"><span class="nav-number">1.5.</span> <span class="nav-text">Bean 解析</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Bean-实例化解析"><span class="nav-number">1.5.1.</span> <span class="nav-text">Bean 实例化解析</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Banner解析"><span class="nav-number">1.6.</span> <span class="nav-text">Banner解析</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#属性配置解析"><span class="nav-number">1.7.</span> <span class="nav-text">属性配置解析</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#属性配置"><span class="nav-number">1.7.1.</span> <span class="nav-text">属性配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Aware"><span class="nav-number">1.7.2.</span> <span class="nav-text">Aware</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Environment-解析"><span class="nav-number">1.7.3.</span> <span class="nav-text">Environment 解析</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring-Boot-特征"><span class="nav-number">1.8.</span> <span class="nav-text">Spring Boot 特征</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#启动失败"><span class="nav-number">1.8.1.</span> <span class="nav-text">启动失败</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#个性化-banner"><span class="nav-number">1.8.2.</span> <span class="nav-text">个性化 banner</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#事件和监听器"><span class="nav-number">1.8.3.</span> <span class="nav-text">事件和监听器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Web-Environment"><span class="nav-number">1.8.4.</span> <span class="nav-text">Web Environment</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ApplicationRunner-or-CommandLineRunner"><span class="nav-number">1.8.5.</span> <span class="nav-text">ApplicationRunner or CommandLineRunner</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Application-Exit"><span class="nav-number">1.8.6.</span> <span class="nav-text">Application Exit</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Externalized-Configuration"><span class="nav-number">1.8.7.</span> <span class="nav-text">Externalized Configuration</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#配置随机值"><span class="nav-number">1.8.7.1.</span> <span class="nav-text">配置随机值</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Application-Property-Files"><span class="nav-number">1.8.7.2.</span> <span class="nav-text">Application Property Files</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Profile-specific-Properties"><span class="nav-number">1.8.7.3.</span> <span class="nav-text">Profile-specific Properties</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Placeholders-in-Properties"><span class="nav-number">1.8.7.4.</span> <span class="nav-text">Placeholders in Properties</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Using-YAML-Instead-of-Properties"><span class="nav-number">1.8.7.5.</span> <span class="nav-text">Using YAML Instead of Properties</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Type-safe-Configuration-Properties"><span class="nav-number">1.8.7.6.</span> <span class="nav-text">Type-safe Configuration Properties</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#Third-Party-Configuration"><span class="nav-number">1.8.7.6.1.</span> <span class="nav-text">Third-Party Configuration</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Relaxed-Binding"><span class="nav-number">1.8.7.6.2.</span> <span class="nav-text">Relaxed Binding</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Merging-Complex-Types"><span class="nav-number">1.8.7.6.3.</span> <span class="nav-text">Merging Complex Types</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Properties-Conersion"><span class="nav-number">1.8.7.6.4.</span> <span class="nav-text">Properties Conersion</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#ConfigurationProperties-Validation"><span class="nav-number">1.8.7.6.5.</span> <span class="nav-text">@ConfigurationProperties Validation</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Profiles"><span class="nav-number">1.8.8.</span> <span class="nav-text">Profiles</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Logging"><span class="nav-number">1.8.9.</span> <span class="nav-text">Logging</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Log-Format"><span class="nav-number">1.8.9.1.</span> <span class="nav-text">Log Format</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Console-Output"><span class="nav-number">1.8.9.2.</span> <span class="nav-text">Console Output</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#File-Output"><span class="nav-number">1.8.9.3.</span> <span class="nav-text">File Output</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Log-Levels"><span class="nav-number">1.8.9.4.</span> <span class="nav-text">Log Levels</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Custom-log-Configuration"><span class="nav-number">1.8.9.5.</span> <span class="nav-text">Custom log Configuration</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Logback-Extensions"><span class="nav-number">1.8.9.6.</span> <span class="nav-text">Logback Extensions</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#JSON"><span class="nav-number">1.8.10.</span> <span class="nav-text">JSON</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Developing-Web-Applications"><span class="nav-number">1.8.11.</span> <span class="nav-text">Developing Web Applications</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Spring-Web-MVC-Framework"><span class="nav-number">1.8.11.1.</span> <span class="nav-text">Spring Web MVC Framework</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Spring-WebFlux-Framework"><span class="nav-number">1.8.11.2.</span> <span class="nav-text">Spring WebFlux Framework</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Embedded-Servlet-Container-Support"><span class="nav-number">1.8.11.3.</span> <span class="nav-text">Embedded Servlet Container Support</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Working-with-NoSQL-Technologies"><span class="nav-number">1.8.12.</span> <span class="nav-text">Working with NoSQL Technologies</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Redis"><span class="nav-number">1.8.12.1.</span> <span class="nav-text">Redis</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#MongoDB"><span class="nav-number">1.8.12.2.</span> <span class="nav-text">MongoDB</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Neo4j"><span class="nav-number">1.8.12.3.</span> <span class="nav-text">Neo4j</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Solr"><span class="nav-number">1.8.12.4.</span> <span class="nav-text">Solr</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Caching"><span class="nav-number">1.8.13.</span> <span class="nav-text">Caching</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Generic"><span class="nav-number">1.8.13.1.</span> <span class="nav-text">Generic</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#JCache"><span class="nav-number">1.8.13.2.</span> <span class="nav-text">JCache</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#EhCache"><span class="nav-number">1.8.13.3.</span> <span class="nav-text">EhCache</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Redis-1"><span class="nav-number">1.8.13.4.</span> <span class="nav-text">Redis</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Caffeine"><span class="nav-number">1.8.13.5.</span> <span class="nav-text">Caffeine</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Messages"><span class="nav-number">1.8.14.</span> <span class="nav-text">Messages</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Calling-REST-Services-with-RestTemplate"><span class="nav-number">1.8.15.</span> <span class="nav-text">Calling REST Services with RestTemplate</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Calling-REST-Services-with-WebClient"><span class="nav-number">1.8.16.</span> <span class="nav-text">Calling REST Services with WebClient</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Creating-Your-Own-Auto-Configuration"><span class="nav-number">1.8.17.</span> <span class="nav-text">Creating Your Own Auto-Configuration</span></a></li></ol></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Issac Young"
      src="/images/author.jpg">
  <p class="site-author-name" itemprop="name">Issac Young</p>
  <div class="site-description" itemprop="description">现代生活工作节奏越来越快，需要有时间和空间沉淀积累，将知识点规划成树，记录自己的感悟心得。</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">26</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
        <span class="site-state-item-count">7</span>
        <span class="site-state-item-name">分类</span>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">19</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/IssacYoung2013" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;IssacYoung2013" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:issacyoung@msn.cn" title="E-Mail → mailto:issacyoung@msn.cn" rel="noopener" target="_blank"><i class="fa fa-fw fa-envelope"></i>E-Mail</a>
      </span>
  </div>
  <div class="cc-license motion-element" itemprop="license">
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" class="cc-opacity" rel="noopener" target="_blank"><img src="/images/cc-by-nc-sa.svg" alt="Creative Commons"></a>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 2020 – 
  <span itemprop="copyrightYear">2024</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Issac Young</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-area-chart"></i>
    </span>
      <span class="post-meta-item-text">站点总字数：</span>
    <span title="站点总字数">64k</span>
</div>


        
<div class="busuanzi-count">
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span class="post-meta-item" id="busuanzi_container_site_uv" style="display: none;">
      <span class="post-meta-item-icon">
        <i class="fa fa-user"></i>
      </span>
      <span class="site-uv" title="总访客量">
        <span id="busuanzi_value_site_uv"></span>
      </span>
    </span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item" id="busuanzi_container_site_pv" style="display: none;">
      <span class="post-meta-item-icon">
        <i class="fa fa-eye"></i>
      </span>
      <span class="site-pv" title="总访问量">
        <span id="busuanzi_value_site_pv"></span>
      </span>
    </span>
</div>








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
<!-- 页面点击小红心 -->
<script type="text/javascript" src="/js/clicklove.js"></script>

